<?php

namespace Api;

/*
|--------------------------------------------------------------------------
| 特性：资源仓库拓展
|--------------------------------------------------------------------------
|
*/

trait RepositoryResourceTrait
{
/**
 * 以下为使用时需要添加的属性
 */

    // /**
    //  * 允许列表查询的每页最大条目
    //  *
    //  * @var int
    //  */
    // private $allowMaxPerPage = 100;

    // /**
    //  * 可见字段
    //  *
    //  * @var array
    //  */
    // private $visible = [
    //     'id',
    // ];

    // /**
    //  * 需要同步输出原始值的字段
    //  *
    //  * @var array
    //  */
    // private $needOriginalColumns = [];


    /**
     * 在类中添加__get()方法，在直接获取属性值时自动调用一次，以属性名作为参数传入并处理
     * @param $propertyName
     *
     * @return int
     */
    public function __get($propertyName)
    {  
        if (preg_match('/Model$/', $propertyName)) {
            return $this->Models[$propertyName]->newInstance();
        }
        else if ($propertyName === 'allowMaxPerPage') {
            return 100;
        }
        else if ($propertyName === 'visible') {
            return ['id'];
        }
        else {
            return $this->$propertyName;
        }
    }


/**
 * 以下为使用时可复写的方法
 */

    /**
     * 获取资源列表 的 条件查询支持
     *
     * @param \Illuminate\Database\Eloquent\Model $model
     * @param array $where
     * @return void
     */
    protected function makeListWhere(&$model, array $where = [])
    {
        // empty($where['column'])
        //     || $model = $model->where('column', $where['column']);

        // empty($where['column-like'])
        //     || $model = $model->where('column', 'like', '%'.str_replace('_', '\_', $where['column-like']).'%');
        
        // isset($where['column']) && $where['column'] === 'isNull'
        //     && $model = $model->whereNull('column');
            
        // isset($where['column']) && $where['column'] === 'notNull'
        //     && $model = $model->whereNotNull('column');
    }

    /**
     * 获取单个资源 的 条件查询支持
     *
     * @param \Illuminate\Database\Eloquent\Model $model
     * @param array $where
     * @return void
     */
    protected function makeFirstWhere(&$model, array $where = [])
    {
        // ...
    }

    /**
     * 获取指定 ID 的资源 的 条件查询支持
     *
     * @param \Illuminate\Database\Eloquent\Model $model
     * @return void
     */
    protected function makeGetWhere(&$model)
    {
        // ...
    }

    /**
     * 获取资源列表
     *
     * @param array $needColumns
     * @param array $where
     * @param int $take
     * @param array $orderBy
     * @return array
     */
    public function list(array $needColumns = ['id'], array $where = [], int $take = 10, array $orderBy = ['id', 'desc'])
    {
        $list = $this->_list($needColumns, $where, $take, $orderBy);
        return $list;
    }

    /**
     * 获取资源列表
     *
     * @param array $needColumns
     * @param array $where
     * @param array $orderBy
     * @param int $needPerPage
     * @return array
     */
    public function pageList(array $needColumns = ['id'], array $where = [], int $needPerPage = 10, array $orderBy = ['id', 'desc'])
    {
        $list = $this->_pageList($needColumns, $where, $needPerPage, $orderBy);
        return $list;
    }

    /**
     * 获取单个资源
     *
     * @param array $needColumns
     * @param array $where
     * @param array $orderBy
     * @return object|null
     */
    public function first(array $needColumns = ['id'], array $where = [], array $orderBy = ['id', 'desc'])
    {
        return $this->_first($needColumns, $where, $orderBy);
    }

    /**
     * 获取指定 ID 的资源
     *
     * @param int $id
     * @param array $needColumns
     * @return object
     * 
     * @throws \Illuminate\Database\Eloquent\ModelNotFoundException
     */
    public function get(int $id, array $needColumns = ['id'])
    {
        return $this->_get($id, $needColumns);
    }

    /**
     * 创建资源并返回详情
     *
     * @param array $attributes
     * @return object
     */
    public function create(array $attributes)
    {
        return $this->_create($attributes);
    }

    /**
     * 更新指定 ID 的资源并返回详情
     *
     * @param int $id
     * @param array $attributes
     * @return object
     * 
     * @throws \Illuminate\Database\Eloquent\ModelNotFoundException
     */
    public function update(int $id, array $attributes)
    {
        return $this->_update($id, $attributes);
    }

    /**
     * 删除指定 ID 的资源
     * 
     * @param  int $id
     * @return void
     * 
     * @throws \Illuminate\Database\Eloquent\ModelNotFoundException
     */
    public function delete(int $id)
    {
        $this->_delete($id);
    }
    
/**
 * 以下为使用时不需要重复定义的方法
 */

    /**
     * 获取资源列表
     *
     * @param array $needColumns
     * @param array $where
     * @param int $take
     * @param array $orderBy
     * @return array
     */
    protected function _list(array $needColumns = ['id'], array $where = [], int $take = 10, array $orderBy = ['id', 'desc'])
    {
        $model = $this->Model;

        // 查询字段
        $columns = array_intersect($needColumns, $this->visible);
        
        // 条件查询
        $this->makeListWhere($model, $where);

        // 排序
        $model = $model->orderBy($orderBy[0], $orderBy[1]);

        // 无分页
        $list = $take ? $model->take($take)->get($columns) : $model->get($columns);

        // 支持获取原字段值
        $listArr = $list->toArray();
        if (isset($this->needOriginalColumns)) {
            foreach ($list as $key => $value) {
                $listArr[$key] = array_merge($listArr[$key], $value->getOriginals($this->needOriginalColumns));
            }
        }
        
        return $listArr;
    }

    /**
     * 获取资源列表
     *
     * @param array $needColumns
     * @param array $where
     * @param int   $needPerPage
     * @param array $orderBy [['created_at', 'desc'], ['id', 'desc']]
     * @return array
     */
    protected function _pageList(array $needColumns = ['id'], array $where = [], int $needPerPage = 10, array $orderBy = ['id', 'desc'])
    {
        $model = $this->Model;
        // 查询字段
        $columns = array_intersect($needColumns, $this->visible);
        
        // 条件查询
        $this->makeListWhere($model, $where);
        
        // 排序
        foreach ($orderBy as $key => $value) {
            if (is_array($value)) {
                $model = $model->orderBy($value[0], $value[1]);
            } else {
                $model = $model->orderBy($orderBy[0], $orderBy[1]);
            }
        }

        // 每页条目
        $perPage = $needPerPage < $this->allowMaxPerPage ? $needPerPage : $this->allowMaxPerPage;
        
        // 分页
        $list = $model->paginate($perPage, $columns);
        // 支持获取原字段值
        $listArr = $list->toArray();
        if (isset($this->needOriginalColumns)) {
            foreach ($list as $key => $value) {
                $listArr['data'][$key] = array_merge($listArr['data'][$key], $value->getOriginals($this->needOriginalColumns));
            }
        }
        
        return $listArr;
    }

    /**
     * 获取单个资源
     *
     * @param array $needColumns
     * @param array $where
     * @param array $orderBy
     * @return object|null
     */
    protected function _first(array $needColumns = ['id'], array $where = [], array $orderBy = ['id', 'desc'])
    {
        $model = $this->Model;

        // 查询字段
        $columns = array_intersect($needColumns, $this->visible);
        
        // 条件查询
        $this->makeFirstWhere($model, $where);

        // 排序
        $model = $model->orderBy($orderBy[0], $orderBy[1]);

        // 开始查询
        if (isset($this->needOriginalColumns)) {
            return $model->first($columns)->mergeOriginals($this->needOriginalColumns);
        } else {
            return $model->first($columns);
        }
    }

    /**
     * 获取指定 ID 的资源
     *
     * @param int $id
     * @param array $needColumns
     * @return object
     * 
     * @throws \Illuminate\Database\Eloquent\ModelNotFoundException
     */
    protected function _get(int $id, array $needColumns = ['id'])
    {
        $model = $this->Model;

        // 查询字段
        $columns = array_intersect($needColumns, $this->visible);
        
        // 条件查询
        $this->makeGetWhere($model);

        // 开始查询
        if (isset($this->needOriginalColumns)) {
            return $model->findOrFail($id, $columns)->mergeOriginals($this->needOriginalColumns);
        } else {
            return $model->findOrFail($id, $columns);
        }
        
    }

    /**
     * 创建资源并返回详情
     *
     * @param array $attributes
     * @return object
     */
    protected function _create(array $attributes)
    {
        $model = $this->Model;

        $model->forceFill($attributes);

        // 写入数据
        $model->saveOrFail();
        return $model;
    }

    /**
     * 更新指定 ID 的资源并返回详情
     *
     * @param int $id
     * @param array $attributes
     * @return object
     * 
     * @throws \Illuminate\Database\Eloquent\ModelNotFoundException
     */
    protected function _update(int $id, array $attributes)
    {
        $model = $this->Model->findOrFail($id);

        $model->forceFill($attributes);
        
        // 写入数据
        $model->saveOrFail();
        return $model;
    }

    /**
     * 删除指定 ID 的资源
     * 
     * @param  int $id
     * @return void
     * 
     * @throws \Illuminate\Database\Eloquent\ModelNotFoundException
     */
    protected function _delete(int $id)
    {
        $this->Model->findOrFail($id)->delete();
    }


}
